import {
  defineComponent,
  inject,
  type Ref,
  type ExtractPropTypes,
  type VNode,
  type PropType,
} from 'vue';

import { tableContextInjectKey } from '../table/table';

import { type State } from '../libs/constant';
import { createNamespace } from '../libs/bem';

type StateRef = Ref<State>;

type OperationButton = {
  type: 'primary' | 'success' | 'warning' | 'danger' | 'info';
  size: 'small' | 'default' | 'large';
  plain: boolean;
  icon: any;
  label: string;
  link: boolean;
  class: string;
};

export const defaultButton: OperationButton = {
  type: 'primary',
  size: 'small',
  plain: true,
  icon: '',
  label: '',
  link: false,
  class: '',
};

export type ButtonType = 'add' | 'del' | 'edit' | 'save' | 'copy';
export type Buttons = ('add' | 'del' | 'edit' | 'save' | 'copy')[];

export const defaultButtons = ['edit', 'save', 'add', 'copy', 'del'];
export const defaultButtonNames = {
  add: '添加',
  del: '删除',
  edit: '编辑',
  save: '保存',
  copy: '复制',
};

const props = {
  label: {
    type: String,
    default: '',
  },
  prop: {
    type: String,
    default: '',
  },
  extra: {
    type: Boolean,
    default: false,
  },
  width: {
    type: [String, Number],
    default: '1fr',
  },
  operation: {
    type: Boolean,
    default: false,
  },
  buttons: {
    type: Array as PropType<Buttons>,
    default: () => defaultButtons,
  },
  add: {
    type: Object as PropType<Partial<OperationButton>>,
    default: () => ({}),
  },
  del: {
    type: Object as PropType<Partial<OperationButton>>,
    default: () => ({}),
  },
  edit: {
    type: Object as PropType<Partial<OperationButton>>,
    default: () => ({}),
  },
  save: {
    type: Object as PropType<Partial<OperationButton>>,
    default: () => ({}),
  },
  copy: {
    type: Object as PropType<Partial<OperationButton>>,
    default: () => ({}),
  },
};

type TableColumnProps = ExtractPropTypes<typeof props>;

export type RenderData = {
  row: object;
  index: number;
  data: any[];
};

export type ColumnRender = (
  data: RenderData,
  state: StateRef
) => VNode | VNode[];

export type StateRender = {
  view: (data: RenderData) => VNode | VNode[];
  edit: (data: RenderData) => VNode | VNode[];
  solid: (data: RenderData) => VNode | VNode[];
};

export interface TableColumnConfig extends TableColumnProps {
  // render: ColumnRender;
  slot?: (scope: RenderData) => VNode[];
}

export default defineComponent({
  name: 'extra-table-column',
  props,
  setup(props, { slots }) {
    const {
      label,
      prop,
      width,
      extra,
      operation,
      buttons,
      add,
      del,
      edit,
      save,
      copy,
    } = props;
    const tableContext = inject(tableContextInjectKey);
    if (tableContext) {
      const bem = createNamespace('extra-table-button');

      const composeButtonConfig = (
        newConfig: Partial<OperationButton>,
        required: Partial<OperationButton>
      ) => {
        const config = Object.assign({}, defaultButton, {
          ...required,
          ...newConfig,
        });
        config.class += ` ${bem.m(required.class)}`;
        return config;
      };

      const columnConfig = {
        label,
        prop,
        width,
        extra,
        // render,
        slot: slots.default,

        operation,
        buttons,
        add: composeButtonConfig(add, {
          label: '添加',
          class: 'add',
        }),
        del: composeButtonConfig(del, {
          label: '删除',
          type: 'danger',
          class: 'del',
        }),
        edit: composeButtonConfig(edit, {
          label: '编辑',
          class: 'edit',
        }),
        save: composeButtonConfig(save, {
          label: '保存',
          class: 'save',
        }),
        copy: composeButtonConfig(copy, {
          label: '复制',
          class: 'copy',
        }),
      };

      tableContext.registryColumns(columnConfig);
    }

    return () => '';
  },
});

//
